<!--
 * @Author: hongbin
 * @Date: 2021-10-11 07:11:55
 * @LastEditTime: 2021-10-11 16:03:40
 * @Description: 用canvas实现键盘输入文字效果
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas {
            border: 1px solid #000;
            /* background: #000; */
        }
    </style>
</head>

<body>
    <canvas id="textOutput"></canvas>

    <script>
        const canvasWidth = 400;
        const canvasHeight = 400;
        const canvas = document.getElementById('textOutput');
        canvas.width = canvasWidth;
        canvas.height = canvasHeight;
        const ctx = canvas.getContext("2d");

        ctx.clearRect(0, 0, canvasWidth, canvasHeight);

        const str = 'HELLO 我是宏斌一名大前端开发工程狮\n出生年月日: 2000/08/20\n星座: 狮子座\n学历: 本科\n毕业年份: 2023\n专业: 计算机科学与技术\n能快速学习掌握新技术，喜欢学习并尝试新技术\n有前端/移动端网页 小程序 App 后端 开发经验\n喜欢交流，互相学习，与其他开发人员交流总让我感到愉悦\n对前端发展感到振奋';
        const startSpot = [10, 10];//开始点
        const currentSpot = [...startSpot];//记录当前的坐标
        const fontSize = 20;//字体
        const mediumFontSize = 15;//字体
        const smallFontSize = 12;//字体
        const lingHeight = 5;//行间距

        const drawText = (text, x, y) => {
            ctx.beginPath();
            ctx.font = `${fontSize}px Arial Rounded MT Bold, Helvetica Rounded, Arial, sans-serif`;
            ctx.fillStyle = '#' + parseInt(Math.random() * 0xffffff).toString(16);
            ctx.textBaseline = "top";
            ctx.fillText(text, x, y);
            ctx.closePath();
        }

        const drawVerticalLine = (x, start, end) => {
            ctx.beginPath();
            ctx.moveTo(x, start);
            ctx.lineTo(x, end);
            ctx.strokeStyle = '#000';
            ctx.stroke();
            ctx.closePath();
        }

        let index = 0;//画到第几个字符了
        const space = 50;

        //换行
        const lineFeed = () => {
            currentSpot[1] += fontSize + lingHeight;
            currentSpot[0] = startSpot[0];
        }

        function draw() {
            const char = str[index++];
            //清除上一条插入点
            ctx.clearRect(currentSpot[0] + 9, currentSpot[1], 2, fontSize);
            if (!char) return;
            // console.log(char);
            if (char == '\n') lineFeed()
            else {
                if (currentSpot[0] > canvasWidth - fontSize) lineFeed();
                //如果是字母或斜线 空格 间距要小点
                let size = fontSize;
                const smallChar = /[A-Za-z0-9/ ]/.test(char);
                if (smallChar) size = /[A-Z0-9]/.test(char) ? mediumFontSize : smallFontSize
                drawText(char, ...currentSpot);//画一个文字
                currentSpot[0] += size;//绘画点向右移动
                drawVerticalLine(currentSpot[0] + 10, currentSpot[1], currentSpot[1] + fontSize);
            }
            setTimeout(() => draw(), space);
        }

        setTimeout(() => draw(), space)

    </script>
</body>

</html>